package com.ls.herostory.channel.handler;

import com.google.protobuf.GeneratedMessageV3;
import com.google.protobuf.Message;
import com.ls.herostory.msg.GameMsgProtocol;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.Map;

/**
 * @author liangsu
 * @version v1.0
 * @Description
 * @Date 2020/10/12 11:26
 * @since
 */
public class GameMsgRecognizer {
    private final static Logger logger = LoggerFactory.getLogger(GameMsgRecognizer.class);
    /**
     * 返回消息类，对应的msgCode
     */
    private static Map<Class, GameMsgProtocol.MsgCode> resultToMsgCode = new HashMap<>();
    /**
     * msgCode对应的消息解码器
     */
    static Map<GameMsgProtocol.MsgCode, GeneratedMessageV3> msgCodeToMsgBuilder = new HashMap<>();

    public static void init(){
        //
        Map<String, GameMsgProtocol.MsgCode> msgCodeMap = new HashMap<>();
        GameMsgProtocol.MsgCode[] msgCodes = GameMsgProtocol.MsgCode.values();
        for (GameMsgProtocol.MsgCode msgCode : msgCodes) {
            String key = msgCode.name().replaceAll("_", "").toLowerCase();
            msgCodeMap.put(key, msgCode);
        }

        // 注册
        Class<?>[] declaredClasses = GameMsgProtocol.class.getDeclaredClasses();
        for (Class<?> clazz : declaredClasses) {

            if(clazz.getName().endsWith("Result")){ // 结果类
                GameMsgProtocol.MsgCode msgCode = msgCodeMap.get(clazz.getSimpleName().toLowerCase());
                if(msgCode != null){
                    resultToMsgCode.put(clazz, msgCode);
                    logger.info("注册Result类{}的msgCode {}", clazz.getName(), msgCode);
                }else{
                    logger.warn("Result类{}没有找到匹配的msgCode", clazz.getName());
                }


            }else if(clazz.getName().endsWith("Cmd")){ // 命令类
                GameMsgProtocol.MsgCode msgCode = msgCodeMap.get(clazz.getSimpleName().toLowerCase());

                if(msgCode != null){
                    try {
                        GeneratedMessageV3 messageV3 = (GeneratedMessageV3) clazz.getDeclaredMethod("getDefaultInstance").invoke(clazz);
                        msgCodeToMsgBuilder.put(msgCode, messageV3);
                        logger.info("注册Cmd类{}的msgCode {}", clazz.getName(), msgCode);
                    } catch (IllegalAccessException e) {
                        logger.error(e.getMessage(), e);
                    } catch (InvocationTargetException e) {
                        logger.error(e.getMessage(), e);
                    } catch (NoSuchMethodException e) {
                        logger.error(e.getMessage(), e);
                    }

                }else{
                    logger.warn("Cmd类{}没有找到匹配的msgCode", clazz.getName());
                }
            }
        }
    }

    public static GameMsgProtocol.MsgCode getMsgCodeByResultClass(Class resultClass){
        return resultToMsgCode.get(resultClass);
    }


    public static Message.Builder getMsgBuilder(GameMsgProtocol.MsgCode msgCode){
        GeneratedMessageV3 generatedMessageV3 = msgCodeToMsgBuilder.get(msgCode);

        if(generatedMessageV3 != null){
            return generatedMessageV3.newBuilderForType();
        }

        return null;
    }

}
